package person.wend.javalearnexample.util;

import java.util.*;

public class CollectionsExample {
    public static void main(String[] args) {
        // 1. 使用 sort 对列表进行排序
        sortList();

        // 2. 查找元素（二分查找，要求列表已排序）
        binarySearch();

        // 3. 反转列表元素顺序
        reverseList();

        // 4. 填充列表
        fillList();

        // 5. 获取最大值和最小值（自然顺序）
        getMaxAndMin();

        // 6. 创建不可变列表视图示例
        createImmutableList();


        // 7. 创建线程安全的列表
        synchronizedList();

        // 8. copy,nCopies 拷贝一个List
        Copy();

        // 9 ：shuffle 对ArrayList进行洗牌
        shuffleList();

        // 10 ：swap 交换列表中的元素
        swapList();

        // 11 ：rotate 向右旋转列表中的元素
        rotateList();

        // 12 ：replaceAll 替换列表中的元素
        replaceAll();

        // 13 ：indexOfSubList 和 lastIndexOfSubList 查找子列表的位置
        indexOfSubList();

        // 14 : 使用checkedCollection创建类型检查集合
        checkedCollection();

        // 15. 创建空集合,单元素集合
        emptyAndSingleton();

        // 16.frequency 计算元素出现的次数
        frequency();

        // 17.disjoint 判断两个集合是否有交集
        disjoint();

        // 18. 使用newSetFromMap创建基于Map的Set
        newSetFromMap();
    }

    // 示例1 ：使用 sort 对列表进行排序
    private static void sortList() {

        // 创建一个整数列表
        List<Integer> numberList = new ArrayList<>();
        numberList.add(5);
        numberList.add(3);
        numberList.add(8);
        numberList.add(1);

        // 1. 使用sort方法进行自然排序（升序）
        List<Integer> sortedList = new ArrayList<>(numberList);
        Collections.sort(sortedList);
        System.out.println("升序排序后的列表: " + sortedList);

        // 2. 使用自定义Comparator进行降序排序
        Comparator<Integer> reverseComparator = (a, b) -> b - a;
        Collections.sort(numberList, reverseComparator);
        System.out.println("降序排序后的列表: " + numberList);


    }

    // 示例2 ：查找元素（二分查找，要求列表已排序）
    private static void binarySearch() {
        // 创建一个整数列表
        List<Integer> sortedList = new ArrayList<>();
        sortedList.add(1);
        sortedList.add(2);
        sortedList.add(3);
        sortedList.add(4);
        sortedList.add(5);

        // 3. 查找元素（二分查找，要求列表已排序）
        int index = Collections.binarySearch(sortedList, 3);
        System.out.println("元素3在升序排序后的列表中的索引: " + index);
    }

    // 示例3 ：反转列表元素顺序
    private static void reverseList() {
        // 创建一个整数列表
        List<Integer> sortedList = new ArrayList<>();
        sortedList.add(1);
        sortedList.add(2);
        sortedList.add(3);
        sortedList.add(4);
        sortedList.add(5);

        // 4. 反转列表元素顺序
        Collections.reverse(sortedList);
        System.out.println("反转后的列表: " + sortedList);
    }

    // 示例4 ：填充列表
    private static void fillList() {
        // 创建一个字符串列表
        List<String> stringList = new ArrayList<>();
        stringList.add("old");
        Collections.fill(stringList, "new");
        System.out.println("填充后的字符串列表: " + stringList);
    }

    // 示例5 ：获取最大值和最小值（自然顺序）
    private static void getMaxAndMin() {
        List<Integer> numberList = new ArrayList<>();
        numberList.add(10);
        numberList.add(20);
        numberList.add(5);
        System.out.println("最大值（自然顺序）: " + Collections.max(numberList));
        System.out.println("最小值（自然顺序）: " + Collections.min(numberList));
    }

    // 示例6 ：创建不可变列表视图示例
    private static void createImmutableList() {
        List<Integer> sortedList = new ArrayList<>();
        sortedList.add(1);
        sortedList.add(2);
        sortedList.add(3);
        sortedList.add(4);
        sortedList.add(5);

        // 创建不可变列表视图示例
        List<Integer> immutableList = Collections.unmodifiableList(sortedList);
        // 下面这行代码会抛出UnsupportedOperationException异常，因为不可变视图不允许修改
        // immutableList.add(99);
        // 不可变的Set、Map
        Set<Integer> immutableSet = Collections.unmodifiableSet(new HashSet<>(sortedList));
        Map<Integer, String> immutableMap = Collections.unmodifiableMap(new HashMap<>());
    }

    // 示例7 ：使用 synchronizedList 创建线程安全的列表
    private static void synchronizedList() {
        List<Integer> sortedList = new ArrayList<>();
        sortedList.add(1);
        sortedList.add(2);
        sortedList.add(3);
        sortedList.add(4);
        sortedList.add(5);

        // 创建线程安全的列表
        List<Integer> synchronizedList = Collections.synchronizedList(sortedList);
        // 通过synchronizedList获取的列表是线程安全的，但是需要注意的是，对列表的迭代操作仍然需要手动同步
        synchronized (synchronizedList) {
            for (Integer num : synchronizedList) {
                System.out.println(num);
            }
        }
    }

    // 示例8 ：使用 nCopies 创建指定大小的列表，并填充指定元素,使用copy复制一个List
    private static void Copy() {
        List<Integer> sortedList = new ArrayList<>();
        sortedList.add(1);
        sortedList.add(2);
        sortedList.add(3);
        sortedList.add(4);
        sortedList.add(5);

        // 创建一个包含10个元素的列表，每个元素都是0
        List<Integer> copyList = new ArrayList<>(Collections.nCopies(10, 0));
        System.out.println("创建的列表: " + copyList);

        Collections.copy(copyList, sortedList);
        System.out.println("拷贝后: copyList: " + copyList);

    }

    // 示例9 ：使用 shuffle 对列表进行洗牌
    private static void shuffleList() {
        List<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        Collections.shuffle(arrayList);
        System.out.println("Shuffled ArrayList: " + arrayList);

        List<Integer> linkedList = new LinkedList<>();
        linkedList.add(5);
        linkedList.add(6);
        linkedList.add(7);
        linkedList.add(8);
        Collections.shuffle(linkedList);
        System.out.println("Shuffled LinkedList: " + linkedList);
    }

    // 示例10 ：使用 swap 交换列表中的元素
    private static void swapList() {
        // 创建一个包含若干元素的列表
        List<String> fruitList = new ArrayList<>();
        fruitList.add("Apple");
        fruitList.add("Banana");
        fruitList.add("Cherry");
        fruitList.add("Date");

        System.out.println("交换前的列表: " + fruitList);

        // 使用Collections.swap方法交换列表中指定位置的元素
        // 交换索引为1和索引为3的元素（也就是交换 "Banana" 和 "Date"）
        Collections.swap(fruitList, 1, 3);

        System.out.println("交换后的列表: " + fruitList);
    }

    // 示例11 ：使用 rotate 向右旋转列表中的元素
    private static void rotateList() {
        // 创建一个包含若干元素的列表
        List<String> fruitList = new ArrayList<>();
        fruitList.add("Apple");
        fruitList.add("Banana");
        fruitList.add("Cherry");
        fruitList.add("Date");

        // 打印原始列表
        System.out.println("Original list: " + fruitList);

        // 向右旋转列表中的元素，距离为2
        Collections.rotate(fruitList, 2);

        // 打印旋转后的列表
        System.out.println("Rotated list: " + fruitList);
    }

    // 示例12 ：replaceAll 替换列表中的元素
    private static void replaceAll(){
        // 创建一个包含若干元素的列表
        List<String> fruitList2 = new ArrayList<>();
        fruitList2.add("Apple");
        fruitList2.add("Banana");
        fruitList2.add("Cherry");
        fruitList2.add("Date");

        // 打印原始列表
        System.out.println("Original list: " + fruitList2);

        // 使用Collections.replaceAll方法替换列表中的元素 将列表中的 "Banana" 替换为 "Grape"
        Collections.replaceAll(fruitList2, "Banana", "Grape");

        // 打印替换后的列表
        System.out.println("Replaced list: " + fruitList2);
    }

    // 示例13 ：indexOfSubList 和 lastIndexOfSubList 查找子列表的位置
    private static void indexOfSubList(){
        // 创建一个包含若干元素的列表
        List<String> fruitList3 = new ArrayList<>();
        fruitList3.add("Apple");
        fruitList3.add("Banana");
        fruitList3.add("Cherry");
        fruitList3.add("Date");
        fruitList3.add("Apple");
        fruitList3.add("Banana");

        // 创建一个包含若干元素的子列表
        List<String> subList = new ArrayList<>();
        subList.add("Apple");
        subList.add("Banana");

        // 使用Collections.indexOfSubList方法查找子列表的位置
        int index1 = Collections.indexOfSubList(fruitList3, subList);
        System.out.println("Index of sublist: " + index1);

        // 使用Collections.lastIndexOfSubList方法查找子列表的位置
        int index2 = Collections.lastIndexOfSubList(fruitList3, subList);
        System.out.println("Last index of sublist: " + index2);
    }

    // 示例14 : 使用checkedCollection创建类型检查集合
    private static void checkedCollection(){
        ArrayList rawList = new ArrayList<>();
        rawList.add(1);
        rawList.add("hello");

        // 创建一个只允许存放Integer类型元素的检查集合，以rawList为基础
        Collection checkedCollection = Collections.checkedCollection(rawList, Integer.class);

        try {
            // 尝试添加一个符合要求的Integer元素，操作正常
            checkedCollection.add(2);
            // 尝试添加一个不符合要求的String元素，会抛出ClassCastException
            checkedCollection.add("world");
        } catch (ClassCastException e) {
            System.out.println("类型不匹配，出现异常: " + e.getMessage());
        }
    }

    // 示例15. 创建空集合,单元素集合
    private static void emptyAndSingleton(){
        // 示例18. 创建空集合
        List<String> empty = Collections.emptyList();
        System.out.println("创建的空列表: " + empty);
        // 示例19. 创建单元素集合
        List<String> singleton = Collections.singletonList("hello");
        System.out.println("创建的单元素列表: " + singleton);
        // 创建单元素只读Map
        Map<String, Integer> readOnlyMap = Collections.singletonMap("key", 1);
        System.out.println("创建的只读Map: " + readOnlyMap);
        // 创建不可变Set
        Set<String> immutableSet2 = Collections.singleton("hello");
        System.out.println("创建的不可变Set: " + immutableSet2);
    }

    // 示例15.frequency 计算元素出现的次数
    private static void frequency(){
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("apple");

        int count = Collections.frequency(list, "apple");
        System.out.println("元素 'apple' 在列表中出现的次数: " + count);
    }

    // 示例16.disjoint 判断两个集合是否有交集
    private static void disjoint(){
        List<String> list1 = new ArrayList<>();
        list1.add("a");
        list1.add("b");

        List<String> list2 = new ArrayList<>();
        list2.add("c");
        list2.add("d");

        boolean disjoint = Collections.disjoint(list1, list2);
        System.out.println("两个集合是否不相交: " + disjoint);

        List<String> list3 = new ArrayList<>();
        list3.add("a");
        list3.add("e");

        disjoint = Collections.disjoint(list1, list3);
        System.out.println("另外两个集合是否不相交: " + disjoint);
    }

    // 示例17. 使用newSetFromMap创建基于Map的Set
    private static void newSetFromMap(){
        Map<String, Boolean> underlyingMap = new HashMap<>();
        // 基于自定义的Map创建一个Set
        Set<String> customSet = Collections.newSetFromMap(underlyingMap);

        customSet.add("element1");
        customSet.add("element2");

        System.out.println("基于Map创建的Set: " + customSet);
        System.out.println("对应的Map内容: " + underlyingMap);
    }





}
